package ooo.reindeer.data.util;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.ByteBufUtil;
import ooo.reindeer.data.decoder.IFrameDecoder;

import java.io.InputStream;

public class DataReader {
    private final InputStream inputStream;
    private final IFrameDecoder frameDecoder;
    private final ByteBufAllocator alloc;
    private ByteBuf buf;

    DataReader(InputStream inputStream, IFrameDecoder frameDecoder) throws Exception {
        this(inputStream, frameDecoder, ByteBufAllocator.DEFAULT);
    }

    private DataReader(InputStream inputStream, IFrameDecoder frameDecoder, ByteBufAllocator alloc) throws Exception {
        this.inputStream = inputStream;
        this.frameDecoder = frameDecoder;
        this.alloc = alloc;
        buf = alloc.buffer();
    }

    private synchronized ByteBuf read() throws Exception {

        if (buf.readableBytes() > 0) {
            ByteBuf temp = alloc.buffer();
            try {
                temp.writeBytes(buf);
            } finally {
                if (buf != null) {
                    buf.release();
                }

            }
            buf = temp;
        }
        return frameDecoder.decode(buf, inputStream);

    }

    public synchronized byte[] readBytes() throws Exception {

        ByteBuf byteBuf = null;
        try {
            byteBuf = read();
            if (byteBuf!=null) {
                return ByteBufUtil.getBytes(byteBuf);
            }else{
                return null;
            }
        } finally {
            if(byteBuf!=null) {
                byteBuf.release();
            }
        }

    }

    public synchronized <T> T readObject(Class<T> clazz) throws Exception {

        ByteBuf byteBuf = null;
        try {
            byteBuf = read();
            T t=null;
            if (byteBuf!=null) {
                t = ByteDataUtil.toObject(byteBuf, clazz);
            }
            return t;
        } finally {
            if(byteBuf!=null) {
                byteBuf.release();
            }
        }

    }

}
